package com.xls.aclservice.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xls.aclservice.entity.SysUser;
import com.xls.aclservice.feign.OssFileService;
import com.xls.base.exception.BusinessException;
import com.xls.aclservice.entity.SysUserRole;
import com.xls.aclservice.mapper.SysUserMapper;
import com.xls.aclservice.service.SysUserRoleService;
import com.xls.aclservice.service.SysUserService;
import com.xls.aclservice.vo.UserQuery;
import com.xls.entity.SecurityUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author xls
 * @since 2021-03-23
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private SysUserRoleService sysUserRoleService;

    @Autowired
    private OssFileService ossFileService;

    public Page<SysUser> getUserPage(Integer page, Integer limit, UserQuery userQuery) {
        QueryWrapper<SysUser> userQueryWrapper = new QueryWrapper<>();
        String username = userQuery.getUsername();
        String name = userQuery.getName();
        String gender = userQuery.getGender();
        String phone = userQuery.getPhone();
        String status = userQuery.getStatus();
        userQueryWrapper.likeRight(!StringUtils.isEmpty(username), "username", username)
                .likeRight(!StringUtils.isEmpty(name), "name", name)
                .eq(!StringUtils.isEmpty(gender), "gender", gender)
                .likeRight(!StringUtils.isEmpty(phone), "phone", phone)
                .eq(!StringUtils.isEmpty(status), "status", status)
                .eq("is_deleted", 0);
        return sysUserMapper.getUserPage(new Page<>(page, limit), userQueryWrapper);
    }

    /**
     * 保存用户并且设置用户角色
     *
     * @param sysUser
     */
    @Override
    @Transactional
    public void saveUser(SysUser sysUser) {
        if (sysUser.getPassword() != null && !"".equals(sysUser.getPassword())) {
            if (!sysUser.getPassword().matches("^(\\w){6,20}$")) {
                throw new BusinessException(6666, "密码只能输入6-20个字母、数字、下划线");
            }
            sysUser.setPassword(passwordEncoder.encode(sysUser.getPassword()));
        } else {
            sysUser.setPassword(null);
        }
        if (sysUser.getId() == null && sysUser.getPassword() == null) {
            sysUser.setPassword("123456");
        }
        validateUser(sysUser);
        this.saveOrUpdate(sysUser);
        setUserRole(sysUser);
    }

    private void validateUser(SysUser sysUser) {
        QueryWrapper<SysUser> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("username", sysUser.getUsername())
                .ne(!StringUtils.isEmpty(sysUser.getId()), "id", sysUser.getId());
        Integer count = sysUserMapper.selectCount(userQueryWrapper);
        if (count > 0) {
            throw new BusinessException(9999, "已存在该用户名");
        }
    }

    /**
     * 批量插入用户角色关联表
     *
     * @param sysUser
     */
    @Transactional
    public void setUserRole(SysUser sysUser) {
        sysUserRoleService.remove(new QueryWrapper<SysUserRole>().eq("user_id", sysUser.getId()));
        List<SysUserRole> sysUserRoleList = new ArrayList<>();
        Long[] roleIds = sysUser.getRoleIds();
        for (Long roleId : roleIds) {
            SysUserRole sysUserRole = new SysUserRole();
            sysUserRole.setUserId(sysUser.getId());
            sysUserRole.setRoleId(roleId);
            sysUserRoleList.add(sysUserRole);
        }
        sysUserRoleService.saveBatch(sysUserRoleList);
    }

    @Override
    public SysUser getUser(Long id) {
        SysUser sysUser = sysUserMapper.getUser(id);
        if (sysUser == null) {
            throw new BusinessException(7777, "用户角色被禁用");
        }
        sysUser.setPassword(null);
        return sysUser;
    }

    @Override
    public SysUser selectByUsername(String username) {
        return sysUserMapper.selectOne(new QueryWrapper<SysUser>().eq("username", username));
    }

    /**
     * 更新用户状态
     *
     * @param sysUser
     */
    @Override
    @Transactional
    public void updateStatus(SysUser sysUser) {
        SysUser oldSysUser = this.getById(sysUser.getId());
        if (oldSysUser.getStatus() != sysUser.getStatus()) {
            sysUserMapper.update(new SysUser(), new UpdateWrapper<SysUser>()
                    .eq("id", sysUser.getId())
                    .set("status", sysUser.getStatus()));
        } else {
            throw new BusinessException(999, "此用户已被他人修改哦!");
        }
    }

    /**
     * 删除用户
     * @param id
     */
    @Override
    @Transactional
    public void removeUser(String id) {
        this.remove(new QueryWrapper<SysUser>().eq("id", id));
        removeUserRole(id);
    }

    /**
     * 删除用户角色关联表
     * @param id
     */
    private void removeUserRole(String id) {
        sysUserRoleService.remove(new QueryWrapper<SysUserRole>().eq("user_id", id));
    }

    @Override
    public SysUser updatePassword(String oldPassword, String newPassword) {
        SecurityUser securityUser = (SecurityUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        SysUser sysUser = this.selectByUsername(securityUser.getUsername());
        if (passwordEncoder.matches(oldPassword, sysUser.getPassword())) {
            sysUserMapper.update(new SysUser(), new UpdateWrapper<SysUser>()
                    .eq("id", sysUser.getId())
                    .set("password", passwordEncoder.encode(newPassword)));
        } else {
            throw new BusinessException(999, "密码错误");
        }
        return null;
    }

    @Override
    public SysUser updateUserProfile(SysUser sysUser) {
        sysUserMapper.updateById(sysUser);
        return sysUser;
    }

    @Override
    @Transactional
    public String uploadAvatar(MultipartFile file, String id) {
        String url = ossFileService.uploadAvatar(file).getData();
        //删除用户原头像
        removeAvatar(id);
        sysUserMapper.update(new SysUser(), new UpdateWrapper<SysUser>()
                .eq("id", id)
                .set("avatar", url));
        return url;
    }

    @Async
    public void removeAvatar(String id) {
        SysUser sysUser = sysUserMapper.selectById(id);
        String avatar = sysUser.getAvatar();
        String url = "http://121.43.155.238:9000/dormitory/";
        if (!avatar.contains("default")) {
            ossFileService.removeAvatar(avatar.substring(url.length()));
        }
    }

}
